﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using InseSoft.Infraestructure;
using InseSoft.Models.Entities;
using InseSoft.ViewModels.Events;
using Ninject;

namespace InseSoft.ViewModels
{
    public class CatalogSearchViewModel : ObservableObject, ICatalogSearchViewModel
    {
        #region Declarations

        private CatalogEntity selectedItem;
        private ObservableCollection<CatalogEntity> filteredList;
        private ObservableCollection<CatalogEntity> recordList;
        private IEventPublisher eventAggregator;
        private string searchPattern;

        #endregion
        
        #region Properties

        [Inject]
        public IEventPublisher EventAggregator
        {
            get { return eventAggregator; }
            set
            {
                eventAggregator = value;
                eventAggregator.GetEvent<EntityAdded>().Subscribe(ItemAdded);
                eventAggregator.GetEvent<EntityRemoved>().Subscribe(ItemRemoved);
            }
        }

        public ObservableCollection<CatalogEntity> RecordList
        {
            get { return recordList; }
            set
            {
                recordList = value;
                OnPropertyChanged(() => RecordList);
                OnPropertyChanged(() => FilteredList);
            }
        }

        public ObservableCollection<CatalogEntity> FilteredList
        {
            get { return filteredList; }
            set
            {
                filteredList = value;
                OnPropertyChanged(() => FilteredList);
            }
        }

        public CatalogEntity SelectedItem
        {
            get { return selectedItem; }
            set
            {
                selectedItem = value;
                OnPropertyChanged(() => SelectedItem);
                EventAggregator.Publish(new EntitySelected(SelectedItem));
            }
        }

        public string SearchPattern
        {
            get { return searchPattern; }
            set
            {
                searchPattern = value;
                OnPropertyChanged(() => SearchPattern);
                UpdateSearchResults();
            }
        }

        #endregion

        #region Methods

        private void ItemAdded(EntityAdded newItem)
        {
            var catalogEntity = newItem.Item as CatalogEntity;
            RecordList.Add(catalogEntity);
            FilteredList = RecordList;
            SelectedItem = catalogEntity;
        }

        private void ItemRemoved(EntityRemoved removedItem)
        {
            var itemToRemove = (from i in recordList
                                where i.Id == removedItem.Item.Id
                                select i).SingleOrDefault();
            RecordList.Remove(itemToRemove);
            FilteredList = RecordList;
            SearchPattern = "";
        }

        public void LoadRecordList(ObservableCollection<CatalogEntity> records)
        {
            RecordList = records;
            FilteredList = records;
        }

        private void UpdateSearchResults()
        {
            var query = (from i in recordList
                         where i.Nombre.ToLower().Contains(SearchPattern.ToLower())
                         select i);
            FilteredList = new ObservableCollection<CatalogEntity>(query);
        }

        #endregion
    }
}
